// Server.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <string>
#include <sys/timeb.h>
#include <sys/types.h>
#include <winsock2.h>

#include "FTDI_Device.hpp"

#define MYPORT 3490

#define BACKLOG 10

#define HTML_STR_ON "HTTP/1.0 200 OK\n Content-Type: text/html\n<HTML>\n\n<HEAD><TITLE>Device Server </TITLE></HEAD>\n<H1> Device Server </H1>\n<H2> Turning Device ON </H2>\n</HTML>\n\n"
#define HTML_STR_OFF "HTTP/1.0 200 OK\n Content-Type: text/html\n<HTML>\n\n<HEAD><TITLE>Device Server </TITLE></HEAD>\n<H1> Device Server </H1>\n<H2> Turning Device OFF </H2>\n</HTML>\n\n"

char commands[][100] = {"OFF",
                        "ON"};


FTDI_Device *device;

/*******************************************************************************/


int
get_cmd (char *rcv_str)
{
    // Scan for command which shows up just after GET
    char *get_cmd;

    get_cmd = strstr(rcv_str, "GET");
    if (NULL == get_cmd) {
        printf("Get not found <%s>\n", rcv_str);
        return 0;
    }

    // Go past GET
    get_cmd = get_cmd + 4;
    for (unsigned int idx = 0; idx < sizeof(commands)/sizeof(commands[0][0]); idx ++) {
        if (strstr(get_cmd, &commands[idx][0])) {
            printf("Cmd match found\n");
            printf("Command sent %s", &commands[idx][0]);
            return idx;
        }
    }
    printf("Cmd match NOT found\n");
    return 0;
}

static
int init_socket_lib ()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD( 1, 1 );

	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
    /* Tell the user that we couldn't find a useable */
    /* winsock.dll.                                  */
    return err;
	}

/* Confirm that the Windows Sockets DLL supports 1.1.*/
/* Note that if the DLL supports versions greater    */
/* than 1.1 in addition to 1.1, it will still return */
/* 1.1 in wVersion since that is the version we      */
/* requested.                                        */

	if ( LOBYTE( wsaData.wVersion ) != 1 ||
		 HIBYTE( wsaData.wVersion ) != 1 ) {
    /* Tell the user that we couldn't find a useable */
    /* winsock.dll.                                  */
		WSACleanup( );
		return -1;   
	}
	return 0;
}

int main(void)
{
    SOCKET sockfd, new_fd;
    struct sockaddr_in my_addr;
    struct sockaddr_in their_addr;
    int sin_size;

	device = new FTDI_Device;
    
	if ( 0 != init_socket_lib()) {
		printf("Socket Library did not initlialize\n");
		exit(1);
	}
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        printf("socket %s", strerror(errno));
        exit(1);
    }

    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(MYPORT);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    memset(&(my_addr.sin_zero), '\0', 8);

    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))
        == -1) {
        printf("bind %s", strerror(errno));
        exit(1);
    }

    if (listen(sockfd, BACKLOG) == -1) {
        printf("listen %s", strerror(errno));
        exit(1);
    }

    while(1) {
        sin_size = sizeof(struct sockaddr_in);
        if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size))
            == -1) {
            exit(1);
        }
        printf("server: got connection from %s",inet_ntoa(their_addr.sin_addr));
        char rcv_str[800];
        int rcv_len;
            
        memset(rcv_str, 80, 0);
        if ((rcv_len = recv(new_fd, rcv_str, sizeof(rcv_str), 0)) == -1) {
            printf("%s:%s","recv", strerror(errno));
            goto err_exit;
        }
        rcv_str[rcv_len - 2] = 0;
        printf("Receive Str:%d:<%s>\n", rcv_len, rcv_str);
        int cmd;
        char snd_str[200];
        // Toggle Device
        int ret_code;
        cmd = get_cmd(rcv_str);
        if (0 == cmd) {
            if (ret_code = device->turn_off()) {
                printf("Device Cannot be turned OFF error %d", ret_code);
            }
            sprintf(snd_str, "%s", HTML_STR_OFF);
            if (send(new_fd, snd_str, (int)strlen(snd_str), 0) == -1) {
                printf("%s:%s","send", strerror(errno));
//                goto err_exit;
            }
        } else {
            if (ret_code = device->turn_on()) {
                printf("Device Cannot be turned ON error %d", ret_code);
            }
            sprintf(snd_str, "%s", HTML_STR_ON);
            if (send(new_fd, snd_str, (int)strlen(snd_str), 0) == -1) {
                printf("%s:%s","send", strerror(errno));
//                goto err_exit;
            }
        }
        closesocket(new_fd);
    }

err_exit:
    printf("Error Exit");
    closesocket(new_fd);
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}

